//-----------------------------------------------------------------------------
// Device
//-----------------------------------------------------------------------------

package com.tiktok.consumerapp;

//-----------------------------------------------------------------------------
// imports
//-----------------------------------------------------------------------------

import java.io.UnsupportedEncodingException;
import java.util.UUID;

import android.content.Context;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;

//-----------------------------------------------------------------------------
// class implementation
//-----------------------------------------------------------------------------

public final class Device
{
    //-------------------------------------------------------------------------
    // statics
    //-------------------------------------------------------------------------

    public static final String kDefaultAndroidId = "9774d56d682e549c";
    public static final String kLogTag           = "Device";

    //-------------------------------------------------------------------------
    // methods
    //-------------------------------------------------------------------------

    /**
     * @return Return a newly generated GUID.
     */
    public static String generateGUID()
    {
        UUID guid = UUID.randomUUID();
        return guid.toString();
    }

    //-------------------------------------------------------------------------

    /**
     * @return Return the device's unique identifier.
     */
    public static String androidId(Context context)
    {
        String androidId = Secure.getString(context.getContentResolver(),
            Secure.ANDROID_ID);
        return androidId;
    }

    //-------------------------------------------------------------------------

    public static String telephonyId(Context context)
    {
        TelephonyManager manager =
            (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        String deviceId = manager.getDeviceId();
        return deviceId;
    }

    //-------------------------------------------------------------------------

    /**
     * Returns a unique UUID for the current android device.  As with all UUIDs, this unique ID is "very highly likely"
     * to be unique across all Android devices.  Much more so than ANDROID_ID is.
     *
     * The UUID is generated by using ANDROID_ID as the base key if appropriate, falling back on
     * TelephonyManager.getDeviceID() if ANDROID_ID is known to be incorrect, and finally falling back
     * on a random UUID that's persisted to SharedPreferences if getDeviceID() does not return a
     * usable value.
     *
     * In some rare circumstances, this ID may change.  In particular, if the device is factory reset a new device ID
     * may be generated.  In addition, if a user upgrades their phone from certain buggy implementations of Android 2.2
     * to a newer, non-buggy version of Android, the device ID may change.  Or, if a user uninstalls your app on
     * a device that has neither a proper Android ID nor a Device ID, this ID may change on reinstallation.
     *
     * Note that if the code falls back on using TelephonyManager.getDeviceId(), the resulting ID will NOT
     * change after a factory reset.  Something to be aware of.
     *
     * Works around a bug in Android 2.2 for many devices when using ANDROID_ID directly.
     *
     * @see http://code.google.com/p/android/issues/detail?id=10603
     * @see http://stackoverflow.com/questions/2785485/is-there-a-unique-android-device-id/3102499#3102499
     *
     * @return a UUID that may be used to uniquely identify your device for most purposes.
     */
    public static String deviceId(Context context)
    {
        // use the android id if possible
        String guid = Device.androidId(context);
        Log.i(kLogTag, String.format("Attemping to use android id %s...", guid));

        // if it's broken, in which case fallback on deviceId, unless it's not available,
        // then fallback on a random number
        if (guid.equals(kDefaultAndroidId)) {
            guid = telephonyId(context);
            Log.i(kLogTag, "Android id broken using telephony...");
        }

        // if neither telephony or deviceid work, just use uuid
        if (guid != null) {
            try {
                guid = UUID.nameUUIDFromBytes(guid.getBytes("utf8")).toString();
            } catch (UnsupportedEncodingException e) {
                guid = null;
            }
        }

        // fall back to random guid
        if (guid == null) {
            Log.i(kLogTag, "Telephony broken using random guid...");
            guid = generateGUID();
        }

        Log.i(kLogTag, String.format("DeviceId: %s", guid));
        return guid;
    }
}
